#include "DHCamera.h"

void GetErrorString(GX_STATUS error_status);
void *ProcGetImage(void* pParam);

GX_DEV_HANDLE g_device = NULL;              ///< 设备句柄
GX_FRAME_DATA g_frame_data = { 0 };         ///< 采集图像参数
bool g_get_image = false;                   ///< 采集线程是否结束的标志：true 运行；false 退出

DHCamera::DHCamera()
{
    // 初始化库
    status = GXInitLib();
    if (status!= GX_STATUS_SUCCESS)
    {
        cout << "error!" << endl;
    }

    // 枚举设备列表
    status = GXUpdateDeviceList(&nDeviceNum, 1000);
    if ((status!= GX_STATUS_SUCCESS)||(nDeviceNum<= 0))
    {
        cout << "error!" << endl;
    }   

    //打开设备
    stOpenParam.accessMode = GX_ACCESS_EXCLUSIVE;
    stOpenParam.openMode = GX_OPEN_INDEX;
    stOpenParam.pszContent = "1";

    status = GXOpenDevice(&stOpenParam, &g_device);

    if (status == GX_STATUS_SUCCESS)
    {
        printf("<Open device success>\n");

        int64_t nPayLoadSize = 0;
        //获取图像buffer大小，下面动态申请内存
        status = GXGetInt(g_device, GX_INT_PAYLOAD_SIZE, &nPayLoadSize);

       if (status == GX_STATUS_SUCCESS && nPayLoadSize > 0)
       {
          //根据获取的图像buffer大小m_nPayLoadSize申请buffer
          g_frame_data.pImgBuf = malloc((size_t)nPayLoadSize);

          //发送开始采集命令
          status = GXSendCommand(g_device, GX_COMMAND_ACQUISITION_START);
       }   
    }  

    //启动接收线程
    ret = pthread_create(&g_acquire_thread, 0, ProcGetImage, 0);

    if(ret != 0)
    {
        printf("<Failed to create the collection thread>\n");
        status = GXCloseDevice(g_device);
        if(g_device != NULL)
        {
            g_device = NULL;
        }
        status = GXCloseLib();
    }
}

DHCamera::~DHCamera()
{
  //发送停止采集命令
  status = GXSendCommand(g_device, GX_COMMAND_ACQUISITION_STOP);
  
  //关闭采集线程
  g_get_image = false;
  ret = pthread_join(g_acquire_thread,NULL);
  if(ret != 0)
  {
      printf("<Failed to release resources>\n");
  }


  //释放图像缓冲区buffer
  free(g_frame_data.pImgBuf); 

  //关闭设备
  status = GXCloseDevice(g_device);

  //释放库
  status = GXCloseLib();


}

void DHCamera::getSrc(Mat& img)
{
  if (status == GX_STATUS_SUCCESS)
  {
      if (g_frame_data.nStatus == GX_FRAME_STATUS_SUCCESS)
      {
        //图像获取成功
       // cout << "图像获取成功！" << endl;
        //对图像进行处理...
        //增加的内容
        m_rgb_image=new char[g_frame_data.nWidth*g_frame_data.nHeight*3];

        img.create(g_frame_data.nHeight,g_frame_data.nWidth,CV_8UC3);

        memcpy(img.data,g_frame_data.pImgBuf,g_frame_data.nWidth*g_frame_data.nHeight);

        DxRaw8toRGB24(g_frame_data.pImgBuf,m_rgb_image,g_frame_data.nWidth, g_frame_data.nHeight,RAW2RGB_NEIGHBOUR,DX_PIXEL_COLOR_FILTER(BAYERBG),false);

        memcpy(img.data,m_rgb_image,g_frame_data.nWidth*g_frame_data.nHeight*3);
       delete[]m_rgb_image;
       m_rgb_image = NULL;
       	/* namedWindow("test",0);
        imshow("test",img);
        waitKey(5);  */
        //到这里增加结束
      // printf("<Successful acquisition : Width: %d Height: %d >\n", g_frame_data.nWidth, g_frame_data.nHeight);
      }
  }
}

//-------------------------------------------------
/**
\brief 采集线程函数
\param pParam 线程传入参数
\return void*
*/
//-------------------------------------------------
void *ProcGetImage(void* pParam)
{
    GX_STATUS status = GX_STATUS_SUCCESS;

    //接收线程启动标志
    g_get_image = true;

    //发送开采命令
    status = GXSendCommand(g_device, GX_COMMAND_ACQUISITION_START);
    if(status != GX_STATUS_SUCCESS)
    {
        GetErrorString(status);
    }
	
    while(g_get_image)
    {
        if(g_frame_data.pImgBuf == NULL)
        {
            continue;
        }

        status = GXGetImage(g_device, &g_frame_data, 100);
        if(status == GX_STATUS_SUCCESS)
        {
            if(g_frame_data.nStatus == 0)
            {
                //printf("<Successful acquisition : Width: %d Height: %d >\n", g_frame_data.nWidth, g_frame_data.nHeight);
            }
        }
    }
}

//----------------------------------------------------------------------------------
/**
\brief  获取错误信息描述
\param  emErrorStatus  错误码

\return void
*/
//----------------------------------------------------------------------------------
void GetErrorString(GX_STATUS error_status)
{
    char *error_info = NULL;
    size_t size = 0;
    GX_STATUS status = GX_STATUS_SUCCESS;
	
    // 获取错误描述信息长度
    status = GXGetLastError(&error_status, NULL, &size);
    if(status != GX_STATUS_SUCCESS)
    {
           GetErrorString(status);
	   return;
    }
	
    error_info = new char[size];
    if (error_info == NULL)
    {
        printf("<Failed to allocate memory>\n");
        return ;
    }
	
    // 获取错误信息描述
    status = GXGetLastError(&error_status, error_info, &size);
    if (status != GX_STATUS_SUCCESS)
    {
        printf("<GXGetLastError call fail>\n");
    }
    else
    {
        printf("%s\n", (char*)error_info);
    }

    // 释放资源
    if (error_info != NULL)
    {
        delete []error_info;
        error_info = NULL;
    }
}
